﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using Reborn_WorldServer.App1AppHandler;
using System.Timers;

namespace Reborn_Server.App1AppHandler
{
    public class Spell_NightVision : Buff, IConsumable
    {
        public Spell_NightVision() 
        {
            minutesLeft = 10;
        }

        public bool MeetsConsumeRequirements(Character character, Loot loot)
        {
            return true;
        }

        public void Consume(Character myCharacter, Loot lootitem)
        {
            TargetCreatureBase = myCharacter;

            if (lootitem.Name.IndexOf("Potion") > -1)
                minutesLeft = 30;
            else
                minutesLeft = 20;

            LockItem lockItem = TargetCreatureBase.GameHandler.GetLockItem(TargetCreatureBase.MapID, TargetCreatureBase.Instance);
            lock (lockItem.LockObj)
            {
                Map CurrentMap = TargetCreatureBase.GameHandler.GetMap(TargetCreatureBase.MapID, TargetCreatureBase.Instance);

                foreach (MapItem mapitem in CurrentMap.MapItems)
                {
                    if (Math.Abs(mapitem.MapX - myCharacter.MapX) <= 8 && Math.Abs(mapitem.MapY - myCharacter.MapY) <= 8)
                    {
                        foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                        {
                            if (creaturebase is Character)
                            {
                                Character character = (Character)creaturebase;
                                character.PlaySound("DrinkBottle", myCharacter.MapX, myCharacter.MapY);
                                character.AddCreatureBase(myCharacter);
                            }
                        }
                    }
                }

                SpellIcon potion = new SpellIcon();
                foreach (KeyValuePair<int, SpellIcon> value in TargetCreatureBase.GameHandler.Spells)
                {
                    if (value.Value.Name == "Night Vision")
                    {
                        potion = value.Value.clone();
                        break;
                    }
                }
                
                this.SpellID = TargetCreatureBase.GameHandler.ItemIDGen.GetSpellID();
                this.spellIcon = potion;

                //Remove existing recall potions
                foreach (Buff buff in TargetCreatureBase.buffManager.Buffs)
                {
                    if (buff.spellIcon.StackType == base.spellIcon.StackType)
                    {
                        buff.RemoveSpell(false, false);
                    }
                }
                TargetCreatureBase.buffManager.AddBuff(this);
                TargetCreatureBase.buffManager.UpdateBuffs();

                if (TargetCreatureBase is Character)
                {
                    List<MapItem> mapItemsToUpdate = new List<MapItem>();
                    foreach (MapItem mapitem in TargetCreatureBase.currentMapItem.mapItemsWithin4)
                    {
                        if (mapitem.isNaturalDark == true)
                            mapItemsToUpdate.Add(mapitem);
                    }

                    Character targetCharacter = (Character)TargetCreatureBase;
                    targetCharacter.AddMapItems(mapItemsToUpdate, false);
                }
                
                

                spellTimer.Start();
            }
        }

        override public void Resume(CreatureBase targetCreatureBase, SpellIcon _spellIcon, int timeRemaining, int castLevel, int castCharacterID, int castInt, int castWis, int optionalValue, string xmlData)
        {
            minutesLeft = timeRemaining;
            base.Resume(targetCreatureBase, _spellIcon, timeRemaining, castLevel, castCharacterID, castInt, castWis, optionalValue, xmlData);

            if (TargetCreatureBase is Character)
            {
                List<MapItem> mapItemsToUpdate = new List<MapItem>();
                foreach (MapItem mapitem in TargetCreatureBase.currentMapItem.mapItemsWithin4)
                {
                    if (mapitem.isNaturalDark == true)
                        mapItemsToUpdate.Add(mapitem);
                }

                Character targetCharacter = (Character)TargetCreatureBase;
                targetCharacter.AddMapItems(mapItemsToUpdate, false);
            }
            
            spellTimer.Start();
        }

        public override void RemoveSpell(bool updateBuffs, bool sendMessage)
        {
            LockItem lockitem = TargetCreatureBase.GameHandler.GetLockItem(TargetCreatureBase.MapID, TargetCreatureBase.Instance);
            lock (lockitem.LockObj)
            {
                //CHECK IF WE'RE IN A VALID STATE TO CONTINUE EXECUTION/////////////////////////

                //Create a delegate for this method incase it cant be run right now
                Action<bool, bool> thisMethod = (Action<bool, bool>)RemoveSpell;
                //Record this method's arguments
                Object[] thisMethodArgs = { updateBuffs, sendMessage };
                //Pass the delegate and args when we check if we're mid map transfer. If yes, they will be recorded and run again automatically.
                if (TargetCreatureBase.isChangingMaps(thisMethod, thisMethodArgs))
                {
                    //Re-Increment the counter since this method will be re-invoked after the transfer.
                    ticksLeft++;
                    return;
                }
                //A map transfer happened, but its already complete. Immediately re-run this method on a different thread. 
                //We need to use a different thread because otherwise the current thread would lock 2 maps possibly resulting in a deadlock.
                if (TargetCreatureBase.MapID != lockitem.MapID)
                {
                    //Re-Increment the counter since this method will be re-invoked after the transfer.
                    ticksLeft++;

                    thisMethod.BeginInvoke(updateBuffs, sendMessage, null, null);
                    return;
                }
                //STATE IS VALID, CONTINUE EXECUTION///////////////////////////////////////////

                //This buff has been removed, do nothing (this can occur if the buff gets overwritten exactly when this timer fires)
                if (TargetCreatureBase.buffManager.hasBuff(this.SpellID) == false)
                    return;

                base.RemoveSpell(updateBuffs, sendMessage);

                if (TargetCreatureBase is Character)
                {
                    List<MapItem> mapItemsToUpdate = new List<MapItem>();
                    foreach (MapItem mapitem in TargetCreatureBase.currentMapItem.mapItemsWithin4)
                    {
                        if (mapitem.isNaturalDark == true)
                            mapItemsToUpdate.Add(mapitem);
                    }

                    Character targetCharacter = (Character)TargetCreatureBase;
                    targetCharacter.AddMapItems(mapItemsToUpdate, false);
                }
            }
        }

        public void Cast(CreatureBase myCreatureBase, int CastLevel, long CreatureGUID)
        {
            List<MapItem> MapItemsWithin12;
            if (base.InitializeCast(myCreatureBase, CastLevel, CreatureGUID, true, out MapItemsWithin12) == false)
                return;

            minutesLeft = CastLevel + (CastingCreatureWis / 5);

            TargetCreatureBase.buffManager.UpdateBuffs();

            //Start Spell Timer
            spellTimer.Start();

            if (TargetCreatureBase is Character)
            {
                List<MapItem> mapItemsToUpdate = new List<MapItem>();
                foreach (MapItem mapitem in TargetCreatureBase.currentMapItem.mapItemsWithin4)
                {
                    if (mapitem.isNaturalDark == true)
                        mapItemsToUpdate.Add(mapitem);
                }

                Character targetCharacter = (Character)TargetCreatureBase;
                targetCharacter.AddMapItems(mapItemsToUpdate, false);
            }
        }
    }
}
